home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_01_04 / 1n04011a < prev    next >
Text File  |  1990-08-05  |  6KB  |  289 lines

  1. /*
  2.     Header:     FileSrch
  3.     Version:    1.00    03-Mar-1990
  4.  
  5.     Language:   ANSI C with MS-DOS extensions
  6.     Environ:    MS-DOS
  7.  
  8.     Purpose:    This module will search subdirectories for files.
  9.  
  10.     Written by: Scott Robert Ladd
  11. */
  12.  
  13. #if defined(__TURBOC__)
  14.     #include "dir.h"
  15. #else
  16.     #include "direct.h"
  17. #endif
  18.  
  19. #include "dos.h"
  20. #include "stddef.h"
  21. #include "stdlib.h"
  22. #include "string.h"
  23. #include "filesrch.h"
  24.  
  25. #if defined(M_I86SM) || defined(M_I86MM) || defined(__TINY__) ||
  26.     defined(__SMALL__) || defined(__MEDIUM__) || defined(SPTR)
  27.     #define SMALL_DATA_PTRS
  28. #endif
  29.  
  30. #define MAX_SPEC 128
  31.  
  32. /* global data */
  33.  
  34. static char * OrigSpec;
  35. static char   SearchAttr;
  36. static void (* FileHandler)(char * dir, FILE_DATA * fd);
  37.  
  38. static union  REGS  Regs;
  39. static struct SREGS SegRegs;
  40.  
  41. static unsigned OldDTA_Seg;
  42. static unsigned OldDTA_Off;
  43.  
  44. /* local function prototypes */
  45.  
  46. static void TreeFindWork(char * dir_spec);
  47. static void SetDTA(void * new_dta);
  48. static void ResetDTA(void);
  49.  
  50. /* actual program code! */
  51.  
  52. void TreeFind(char * spec,
  53.               char attr,
  54.               char * dir,
  55.               void (* handler)(char * dir, FILE_DATA * fd))
  56.     {
  57.     char * start_dir;
  58.     char * orig_dir;
  59.  
  60.     if (spec != NULL)
  61.         OrigSpec = strdup(spec);
  62.     else
  63.         OrigSpec = "*.*";
  64.  
  65.     SearchAttr = attr;
  66.     FileHandler = handler;
  67.  
  68.     if (dir != NULL)
  69.         {
  70.         orig_dir = malloc(MAX_SPEC);
  71.         getcwd(orig_dir,MAX_SPEC);
  72.         start_dir = strdup(dir);
  73.         }
  74.     else
  75.         {
  76.         orig_dir = NULL;
  77.         start_dir = malloc(MAX_SPEC);
  78.         getcwd(start_dir,MAX_SPEC);
  79.         }
  80.  
  81.     TreeFindWork(start_dir);
  82.  
  83.     if (orig_dir != NULL)
  84.         {
  85.         chdir(orig_dir);
  86.         free(orig_dir);
  87.         }
  88.  
  89.     free(start_dir);
  90.     }
  91.  
  92. static void TreeFindWork(char * dir_spec)
  93.     {
  94.     typedef struct dir_entry
  95.         {
  96.         char * direct;
  97.         struct dir_entry * next;
  98.         }
  99.         DIR_ENTRY;
  100.  
  101.     DIR_ENTRY * first_dir, * temp_dir, * cur_dir;
  102.     char * dir_buf, * work_dir;
  103.     FILE_DATA file;
  104.     int res;
  105.  
  106.     work_dir = malloc(MAX_SPEC);
  107.  
  108.     first_dir = malloc(sizeof(DIR_ENTRY));
  109.     cur_dir = first_dir;
  110.     cur_dir->next = NULL;
  111.  
  112.     chdir(dir_spec);
  113.     getcwd(work_dir,64);
  114.  
  115.     res = FindFirst("*.*",(char)0xFF,&file);
  116.  
  117.     while (!res)
  118.         {
  119.         if (WildMatch(file.name, OrigSpec))
  120.             {
  121.             if ((SearchAttr == 0) || (file.attrib & SearchAttr))
  122.                 {
  123.                 FileHandler(work_dir,&file);
  124.                 }
  125.             }
  126.  
  127.         if (((file.attrib & 0x10) == 0x10) && (file.name[0] != '.'))
  128.             {
  129.             cur_dir->direct = strdup(file.name);
  130.             cur_dir->next   = malloc(sizeof(DIR_ENTRY));
  131.             cur_dir         = cur_dir->next;
  132.             cur_dir->next   = NULL;
  133.             }
  134.  
  135.         res = FindNext(&file);
  136.         }
  137.  
  138.     dir_buf = malloc(MAX_SPEC);
  139.     cur_dir = first_dir;
  140.  
  141.     while (cur_dir->next != NULL)
  142.         {
  143.         chdir(work_dir);
  144.         chdir(cur_dir->direct);
  145.  
  146.         getcwd(dir_buf,128);
  147.         TreeFindWork(dir_buf);
  148.  
  149.         temp_dir = cur_dir;
  150.         cur_dir  = cur_dir->next;
  151.  
  152.         free(temp_dir->direct);
  153.         free(temp_dir);
  154.         }
  155.     }
  156.  
  157. int WildMatch(char * name, char * tmpl)
  158.     {
  159.     strupr(name);
  160.     strupr(tmpl);
  161.  
  162.     while ((*name && *name != '.') || (*tmpl && *tmpl != '.'))
  163.         {
  164.         if ((*name != *tmpl) && (*tmpl != '?'))
  165.             {
  166.             if (*tmpl != '*')
  167.                 {
  168.                 return 0;
  169.                 }
  170.             else
  171.                 {
  172.                 while (*name && *name != '.')
  173.                     name++;
  174.                 while (*tmpl && *tmpl != '.')
  175.                     tmpl++;
  176.                 break;
  177.                 }
  178.             }
  179.         else
  180.             {
  181.             name++;
  182.             tmpl++;
  183.             }
  184.         }
  185.  
  186.     if (*name == '.')
  187.         name++;
  188.  
  189.     if (*tmpl == '.')
  190.         tmpl++;
  191.  
  192.     while (*name || *tmpl)
  193.         {
  194.         if ((*name != *tmpl) && (*tmpl != '?'))
  195.             {
  196.             if (*tmpl != '*')
  197.                 return 0;
  198.             else
  199.                 return 1;
  200.             }
  201.         else
  202.             {
  203.             name++;
  204.             tmpl++;
  205.             }
  206.         }
  207.  
  208.     return 1;
  209.     }
  210.  
  211. int FindFirst(char * spec, char attrib, FILE_DATA * fd)
  212.     {
  213.     int res;
  214.  
  215.     SetDTA(fd);
  216.  
  217.     Regs.h.ah = 0x4E;
  218.     Regs.x.cx = (unsigned)attrib;
  219.  
  220.     #if defined(SMALL_DATA_PTRS)
  221.         Regs.x.dx = (unsigned)spec;
  222.         intdos(&Regs,&Regs);
  223.     #else
  224.         segread(&SegRegs);
  225.         SegRegs.ds  = FP_SEG(spec);
  226.         Regs.x.dx = FP_OFF(spec);
  227.         intdosx(&Regs,&Regs,&SegRegs);
  228.     #endif
  229.  
  230.     #if !defined(LATTICE)
  231.         res = Regs.x.cflag;
  232.     #endif
  233.  
  234.     ResetDTA();
  235.  
  236.     return res;
  237.     }
  238.  
  239. int FindNext(FILE_DATA * fd)
  240.     {
  241.     int res;
  242.  
  243.     SetDTA(fd);
  244.  
  245.     Regs.h.ah = 0x4F;
  246.  
  247.     #if defined(LATTICE)
  248.         res = intdos(&Regs,&Regs);
  249.     #else
  250.         intdos(&Regs,&Regs);
  251.         res = Regs.x.cflag;
  252.     #endif
  253.  
  254.     ResetDTA();
  255.  
  256.     return res;
  257.     }
  258.  
  259. static void SetDTA(void * new_dta)
  260.     {
  261.     Regs.h.ah = 0x2F;
  262.     intdosx(&Regs,&Regs,&SegRegs);
  263.  
  264.     OldDTA_Seg = SegRegs.es;
  265.     OldDTA_Off = Regs.x.bx;
  266.  
  267.     Regs.h.ah = 0x1A;
  268.  
  269.     #ifdef SMALL_DATA_PTRS
  270.         Regs.x.dx = (unsigned)(new_dta);
  271.         intdos(&Regs,&Regs);
  272.     #else
  273.         SegRegs.ds  = FP_SEG(new_dta);
  274.         Regs.x.dx = FP_OFF(new_dta);
  275.         intdosx(&Regs,&Regs,&SegRegs);
  276.     #endif
  277.     }
  278.  
  279. static void ResetDTA(void)
  280.     {
  281.     segread(&SegRegs);
  282.  
  283.     Regs.h.ah = 0x1A;
  284.     SegRegs.ds  = OldDTA_Seg;
  285.     Regs.x.dx = OldDTA_Off;
  286.  
  287.     intdosx(&Regs,&Regs,&SegRegs);
  288.     }
  289.